package com.qk.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qk.common.PageResult;
import com.qk.common.contant.ClueTrackRecordType;
import com.qk.common.contant.StatusContant;
import com.qk.common.enums.ParamEnum;
import com.qk.common.exception.CommonException;
import com.qk.common.util.CurrentUserContextHolders;
import com.qk.domain.clue.ClueDO;
import com.qk.domain.user.UserDO;
import com.qk.dto.clue.*;
import com.qk.entity.Business;
import com.qk.entity.Clue;
import com.qk.entity.ClueTrackRecord;
import com.qk.management.mapper.*;
import com.qk.management.service.ClueService;
import com.qk.vo.clue.CluePoolLitsVO;
import com.qk.vo.clue.ClueVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements ClueService {
    @Autowired
    private ClueMapper clueMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ClueTrackRecordMapper clueTrackRecordMapper;
    @Autowired
    private BusinessMapper businessMapper;
    @Autowired
    private ActivityMapper activityMapper;


    @Override
    public PageResult<CluePoolLitsVO> cluePoolSelectPage(CluePoolListDTO dto) {
        Clue clue = BeanUtil.copyProperties(dto, Clue.class);
        clue.setId(dto.getClueId());
        Page<Clue> pages = new Page<>(dto.getPage(), dto.getPageSize());

        Page<Clue> cluePage = this.baseMapper.selectPage(pages, Wrappers.lambdaQuery(Clue.class)
                .eq(Clue::getStatus, StatusContant.FALSE_CLUE)
                .eq(ObjectUtil.isNotEmpty(clue.getId()),Clue::getId, clue.getId())
                .eq(ObjectUtil.isNotEmpty(clue.getChannel()),Clue::getChannel, clue.getChannel())
                .eq(ObjectUtil.isNotEmpty(clue.getPhone()),Clue::getPhone, clue.getPhone()));

        List<Clue> clueList = cluePage.getRecords();
        List<CluePoolLitsVO> cluePoolLitsVOList = new ArrayList<>();
        for (Clue c : clueList) {
            CluePoolLitsVO cluePoolLitsVO = BeanUtil.copyProperties(c, CluePoolLitsVO.class);
            if (ObjectUtil.isNotEmpty(c.getActivityId())){
                cluePoolLitsVO.setActivityName(activityMapper.selectById(clueMapper.selectById(c.getId()).getActivityId()).getName());
            }
            cluePoolLitsVOList.add(cluePoolLitsVO);
        }

        return PageResult.<CluePoolLitsVO>builder()
                .total( (int) cluePage.getTotal())
                .rows(cluePoolLitsVOList)
                .build();
    }


    @Override
    public void falseClue(Integer id, ClueReasonDTO clueReasonDTO) {
        //先进行reason的判空,因为reason时必须字段
        if (ObjectUtil.isNull(clueReasonDTO.getReason())) {
            throw new CommonException(ParamEnum.PARAM_ERROR);
        }

        //一、把线索数据更新到clue表
        //查询到id相对于的线索信息
        Clue clue = this.baseMapper.selectById(id);
        if (ObjectUtil.isNull(clue)) {
            throw new CommonException(ParamEnum.PARAM_ERROR);
        }
        //把线索信息更新到clue表中
        this.baseMapper.update(null, new UpdateWrapper<Clue>()
                .eq("id", id)
                //先把线索状态改为伪线索
                .set("status", StatusContant.FALSE_CLUE)
                //把线索的userId改为null
                .set("user_id", null)
                .set("next_time", null)
                .set("update_time", LocalDateTime.now()));


        //二、把线索记录数据插入到clue_track_record表
        //进行强转
        ClueTrackRecord clueTrackRecord = BeanUtil.copyProperties(clue, ClueTrackRecord.class);
        //添加各种必要信息
        clueTrackRecord.setId(null);
        clueTrackRecord.setClueId(id);
        clueTrackRecord.setType(ClueTrackRecordType.FALSE_CLUE);
        clueTrackRecord.setUserId(CurrentUserContextHolders.get());
        clueTrackRecord.setRecord(clueReasonDTO.getRemark());
        clueTrackRecord.setFalseReason(Integer.valueOf(clueReasonDTO.getReason()));
        clueTrackRecord.setCreateTime(LocalDateTime.now());
        //把clueTrackRecord数据插入到clue_track_record表中
        this.clueTrackRecordMapper.insert(clueTrackRecord);
    }


    @Override
    public void toBusiness(Integer id) {
        //一:将线索状态转为转商机
        //1.获取线索信息
        Clue clue = this.baseMapper.selectById(id);
        //更新时间
        clue.setUpdateTime(LocalDateTime.now());
        //更新状态
        clue.setStatus(StatusContant.CONVERT_TO_BUSINESS);
        //更新clue表数据
        this.baseMapper.updateById(clue);

        //二:在商机表插入数据
        //1.把clue同字段信息强转为business
        Business business = BeanUtil.copyProperties(clue, Business.class);
        //2.添加各种必要信息
        business.setId(null);
        business.setNextTime(null);
        business.setUserId(null);
        business.setClueId(clue.getId());
        business.setStatus(StatusContant.WAIT_FOLLOW_UP);
        business.setCreateTime(LocalDateTime.now());
        business.setUpdateTime(LocalDateTime.now());
        //把business添加到商机表中
        this.businessMapper.insert(business);
    }



    @Override
    public void updateClueInfoById(UpdateClueInfoDTO dto) {
        //获取线索信息,新增clue_track_record表数据
        //将dto中属于clue表 信息拷贝过来
        Clue clue = BeanUtil.copyProperties(dto, Clue.class);
        //补上更新时间
        clue.setCreateTime(LocalDateTime.now());
        //处理状态如果线索第一次被跟进 2待跟进--->3跟进中
        if (dto.getStatus() == StatusContant.WAIT_FOLLOW_UP) {
            clue.setStatus(StatusContant.FOLLOW_UP);
        }
        //更新clue数据表
        this.baseMapper.updateById(clue);

        //修改clue表数据
        //补上创建时间
        ClueTrackRecord ctr = BeanUtil.copyProperties(clue, ClueTrackRecord.class);
        ctr.setCreateTime(LocalDateTime.now());
        //将id置为 null
        ctr.setId(null);
        //设置当前线索跟进记录的 线索id
        ctr.setClueId(clue.getId());
        //设置线索跟进记录状态默认正常跟进 1正常跟进
        ctr.setType(ClueTrackRecordType.NORMAL_FOLLOW_UP);
        //!!!设置跟进用户id当前用户，此时当前用户的id还在拦截器中
        ctr.setUserId(CurrentUserContextHolders.get());
        //插入数据到 clue_track_record表
        //clueTrackRecordMapper.insert(ctr);
        this.clueTrackRecordMapper.insert(ctr);
    }




    @Override
    public ClueVO getClueById(Integer id) {
        //根据id查询线索表获取基础线索信息
        Clue clue = this.baseMapper.selectById(id);
        //根据线索id查询线索记录表获取当前线索跟进记录
        List<ClueTrackRecord> clueTrackRecords = clueTrackRecordMapper
                .selectList(Wrappers.lambdaQuery(ClueTrackRecord.class).in(ClueTrackRecord::getClueId, id));
        /*for (ClueTrackRecord clueTrackRecord : clueTrackRecords) {
            clueTrackRecord.setRecord(String.valueOf(this.clueTrackRecordMapper.selectById(clueTrackRecord.getId())));
        }*/
        //组装数据
        ClueVO clueVO = BeanUtil.copyProperties(clue, ClueVO.class);
        List<ClueVO.ClueTrackRecordVO> ctrList = clueTrackRecords.stream().map(item -> {
            ClueVO.ClueTrackRecordVO vo = BeanUtil.copyProperties(item, ClueVO.ClueTrackRecordVO.class);
            if (ObjectUtil.isNotEmpty(clue.getUserId())) vo.setAssignName(userMapper.getUser(clue.getUserId()).getName());
            return vo;
        }).toList();

        //设置跟进记录
        clueVO.setTrackRecords(ctrList);
        return clueVO;
    }



    //方式二(MP)   MP中如果是夺标查询此时无法使用自带的分页方法,这时可以将分页参数封装到Mapper方法中的第一个参数即可
    //Mapper方法返回值直接使用baomidou的Page
    @Override
    public PageResult<ClueDO> clueList(ClueListDTO dto) {
        Page<ClueDO> pages = new Page<>(dto.getPage(),dto.getPageSize());
//        List<ClueDO> res=this.baseMapper.selectByPageMP(pages,dto);
//        Page<ClueDO> page=(Page<ClueDO>) res;
        Page<ClueDO> page=this.baseMapper.selectByPageMP(pages,dto);
        return PageResult.<ClueDO>builder()
                .total(Long.valueOf(page.getTotal()).intValue())
                .rows(page.getRecords())
                .build();
    }


    /**方式一(pagehelper):
    @Override
    public PageResult<ClueDO> clueList(ClueListDTO dto) {
        PageHelper.startPage(dto.getPage(),dto.getPageSize());
        List<ClueDO> list=this.baseMapper.selectByPage(dto);
        Page<ClueDO> page=(Page<ClueDO>)list;
        PageResult<ClueDO> pageResult = PageResult.<ClueDO>builder()
                .total(Long.valueOf(page.getTotal()).intValue())
                .rows(list)
                .build();

        return pageResult;
    }
    */
    /*PageHelper.startPage(page,pageSize);
        List<Clue> list = clueMapper.list(clueId, phone, status, channel, assignName);

        com.github.pagehelper.Page<Clue> clueList = (com.github.pagehelper.Page<Clue>) list;

        return PageResult.<Clue>builder()
                .total(Long.valueOf(clueList.getTotal()).intValue())
                .rows(list)
                .build();
    }*/

    @Override
    public void addClue(ClueDTO clueDTO) {
        if (ObjectUtil.isEmpty(clueDTO.getPhone()) || ObjectUtil.isEmpty(clueDTO.getChannel())){
            CommonException.throwException(ParamEnum.PARAM_ERROR);
        }
        // 将DTO 转成实体 bean 拷贝
        Clue clue = BeanUtil.copyProperties(clueDTO, Clue.class);
        clue.setCreateTime(LocalDateTime.now());
        clue.setUpdateTime(LocalDateTime.now());
        // 保存线索信息到数据库
        /**
        插入一条记录（选择字段，策略插入）
        @param entity 实体对象

        default boolean save(T entity) {
            return SqlHelper.retBool(getBaseMapper().insert(entity));
        }

        this.save(clue);
        */
        //这段代码的功能是将传入的 clue 对象插入到数据库中。
        //它调用了 MyBatis-Plus 提供的 baseMapper.insert() 方法，
        //执行 SQL 插入操作，将 Clue 实体对象的数据保存到对应的数据库表中
        this.baseMapper.insert(clue);
    }
}